package com.electronic.utils;

import com.electronic.domain.SealSize;
import com.electronic.domain.SubImage;
import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;

@Slf4j
public class ImageDivider {

    private final static int DEFAULT_DPI = 96;
    private final static boolean IS_ADJUST_SIZE_WITH_DPI = true;

    public static ArrayList<SubImage> divideImage(PdfDocument document, byte[] imageData, int startPage, int endPage, int resolution, Rectangle area, float startPercent, float endPercent) throws IOException {
        int increment = 1;
        int totalPages = endPage - startPage + 1;

        ArrayList<SubImage> subImages = new ArrayList<>();

        int imgWidth = 0;
        int imgHeight = 0;
        int imgDpi = DEFAULT_DPI;

        if (ISvgUtil.isSvg(imageData)) {
            try {
                SealSize svgDimensions = ISvgUtil.getSvgSize(imageData);
                imgWidth = (int) svgDimensions.getWidth();
                imgHeight = (int) svgDimensions.getHeight();
            } catch (Exception e) {
                log.error("ISvgUtil.getSvgSize failed:", e);
            }
        } else {
            BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(imageData));
            imgWidth = bufferedImage.getWidth();
            imgHeight = bufferedImage.getHeight();
            ImageData imgData = ImageDataFactory.create(imageData, true);
            imgDpi = imgData.getDpiX();
        }

        if (resolution <= 0) {
            imgDpi = (0 == imgDpi) ? DEFAULT_DPI : imgDpi;
        } else {
            imgDpi = resolution;
        }

        float widthInPoints = (float) imgWidth / imgDpi * 72.0F;
        int widthPoints = (int) (widthInPoints + 0.5F);
        float heightInPoints = (float) imgHeight / imgDpi * 72.0F;
        int heightPoints = (int) (heightInPoints + 0.5F);

        if (!IS_ADJUST_SIZE_WITH_DPI && area != null) {
            float objectWidth = area.getWidth();
            float objectHeight = area.getHeight();
            float maxDimension = Math.max(objectWidth, objectHeight);
            float originalRatio = widthInPoints / heightInPoints;
            float actualRatio = objectWidth / objectHeight;
            widthPoints = (int) area.getWidth();
            heightPoints = (int) area.getHeight();
            if (Math.abs(originalRatio - actualRatio) >= 1.0E-7D) {
                widthPoints = (int) maxDimension;
                heightPoints = (int) (maxDimension / originalRatio);
            }
        }

        processImageSplitting(document, subImages, startPage, endPage, totalPages, increment, heightPoints, widthPoints, startPercent, endPercent);
        return subImages;
    }

    private static void processImageSplitting(PdfDocument document, ArrayList<SubImage> subImages, int startPage, int endPage, int totalPages, int increment, float heightPoints, float widthPoints, float startPercent, float endPercent) {
        float initialWidth = 0.0F;
        float finalWidth = 0.0F;
        float middleWidth = widthPoints;
        if (startPercent > 0.0F) {
            totalPages--;
            initialWidth = widthPoints * startPercent;
            middleWidth = widthPoints - initialWidth;
        }
        if (endPercent > 0.0F) {
            totalPages--;
            finalWidth = widthPoints * endPercent;
            middleWidth -= finalWidth;
        }
        float xOffset = 0.0F;
        float yOffset = 0.0F;
        float previousWidth = 0.0F;
        float eachWidth = middleWidth / totalPages;
        float currentWidth;
        int pageIndex;
        for (pageIndex = startPage; pageIndex <= endPage; pageIndex += increment) {
            SubImage subImage = new SubImage();
            subImage.page = pageIndex;
            PdfPage page = document.getPage(pageIndex);
            //getPageSizeWithRotation考虑了旋转后的尺寸
            //getPageSize获取页面的实际尺寸，不考虑页面的旋转
            Rectangle pageSize = page.getPageSizeWithRotation();
            float x = 0.0F;
            if (initialWidth > 0.0F && pageIndex == startPage) {
                currentWidth = initialWidth;
            } else if (finalWidth > 0.0F && pageIndex + increment > endPage) {
                currentWidth = finalWidth;
            } else {
                currentWidth = eachWidth;
            }
            float y = (pageSize.getHeight() - heightPoints) / 2.0F;
            float width = currentWidth;
            x = pageSize.getWidth() - width;
            if (pageIndex > startPage) {
                xOffset -= previousWidth;
            }
            previousWidth = width;
            subImage.xOffset = xOffset;
            subImage.yOffset = yOffset;
            subImage.imageRect = new Rectangle(x, y, width, heightPoints);
            subImages.add(subImage);
        }
    }

}
